package cn.e4j.core.dto.requestDtoResolver;

import cn.e4j.config.properties.E4jProperties;
import cn.e4j.core.common.constant.JwtConstants;
import cn.e4j.core.dto.IDto;
import cn.e4j.core.dto.impl.Dto;
import cn.e4j.core.shiro.ShiroKit;
import cn.e4j.core.shiro.ShiroUser;
import cn.e4j.core.util.AppCxt;
import cn.e4j.core.util.JwtTokenUtil;
import cn.e4j.modular.system.entity.SysUser;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.http.HttpServletRequest;
import java.util.Iterator;
import java.util.Map;

/**
 * controller接收数据统一转成Dto
 *
 * @author wenchuan.li
 * @date 2018/12/6 16:29
 */
public class DtoParamResolver implements HandlerMethodArgumentResolver {

    @Autowired
    E4jProperties e4jProperties;


    //判断是否支持要转换的参数类型
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(DtoParam.class);
    }

    @SuppressWarnings("unchecked")
    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
        DtoWapper dtoWapper = new DtoWapper();
        Dto dto = dtoWapper.getDto();

        ShiroUser shiroUser = ShiroKit.getUser();
        if (null != shiroUser) {
            dto.put("ENT", shiroUser.getDBC());
            dto.put("ERP_ENT", AppCxt.getParam("ERP_ENT"));
            dto.put("LANG", shiroUser.getLANG());
            dto.put("SITE", shiroUser.getSITE());
            dto.put("ERP", AppCxt.getParam("ERP"));
            dto.put("ERP_Link", AppCxt.getParam("ERP_Link"));
            dto.put("ERP_DB", AppCxt.getParam("ERP_DB"));
        }

        String token = request.getHeader(JwtConstants.AUTH_HEADER);
        if (shiroUser == null && token != null && token != "" && token.length() > 50) {
            token = token.substring(7);
            SysUser user = AppCxt.getUserInfoCache(JwtTokenUtil.getUsernameFromToken(token));
            if(user != null){
                dtoWapper.setSysUser(user);
                dto.put("SITE", user.getBIZ_CODE() == null ? "" : user.getBIZ_CODE());
                dto.put("ENT", user.getDBC());
                dto.put("ERP_ENT", AppCxt.getParam("ERP_ENT"));
                dto.put("LANG", user.getLANG());
                dto.put("ERP", AppCxt.getParam("ERP"));
                dto.put("ERP_Link", AppCxt.getParam("ERP_Link"));
                dto.put("ERP_DB", AppCxt.getParam("ERP_DB"));
                AppCxt.addCurrentThreadUser(Thread.currentThread().getId(), user);

            }
        }

        Map<String, String[]> map = request.getParameterMap();
        Iterator<String> keyIterator = map.keySet().iterator();

        while (keyIterator.hasNext()) {

            String key = keyIterator.next().trim();
            String value = map.get(key)[0].trim();

            if (key.equals(IDto.REQUST_JSON_TAG)) {
                dto.put(IDto.REQUST_JSON_TAG, value.startsWith("[") ? JSONArray.parse(value) : JSONObject.parse(value));
            } else if (key.equals(IDto.SORT)) {
                dto.put(key, JSONObject.parse(value));
            } else {
                dto.put(key, value);
            }
        }

        if (dto.containsKey("page") && dto.containsKey("limit")) {
            Page<Object> page = new Page<>(dto.getLong("page"), dto.getLong("limit"));
            dtoWapper.setPage(page);
        }

        return dtoWapper;
    }

}
